package at.codejedi.sto;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.List;

import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;

import at.codejedi.sto.config.Configuration;
import at.codejedi.sto.controller.MainController;
import at.codejedi.sto.model.combat.CombatLog;
import at.codejedi.sto.model.combat.IBattleStatistic;
import at.codejedi.sto.model.combat.IPlayer;
import at.codejedi.sto.parser.Parser;

public class Console {

	private static void DisplayCommandLine(String fileToOpen)
			throws IOException {
		Parser p = new Parser();
		CombatLog log = p.read(new File(fileToOpen));
		List<IPlayer> players = log.getPlayers();
		for (IPlayer player : players) {
			System.out.println(player.toCommandLineRepresentation());
		}
		return;
	}

	private static void DisplayGUI(final String filePath) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					try {
						// take the menu bar off the jframe
						System.setProperty("apple.laf.useScreenMenuBar", "true");

						// set the name of the application menu item
						System.setProperty(
								"com.apple.mrj.application.apple.menu.about.name",
								"Sto Combat Analyser");

						// set the look and feel
						UIManager.setLookAndFeel(UIManager
								.getSystemLookAndFeelClassName());
					} catch (ClassNotFoundException e) {
						System.out.println("ClassNotFoundException: "
								+ e.getMessage());
					} catch (InstantiationException e) {
						System.out.println("InstantiationException: "
								+ e.getMessage());
					} catch (IllegalAccessException e) {
						System.out.println("IllegalAccessException: "
								+ e.getMessage());
					} catch (UnsupportedLookAndFeelException e) {
						System.out.println("UnsupportedLookAndFeelException: "
								+ e.getMessage());
					}
				} catch (Exception e) {
					System.err.println("Couldn't use system look and feel.");
				}

				MainController controller = new MainController();
				if (filePath != null)
					controller.openCombatLogFile(filePath);
				controller.showView();
			}
		});
		return;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// create Options object
		Options options = new Options();

		// add t option
		options.addOption("?", true, "display Help");

		options.addOption("c", "cli", false, "use the command line interface");

		CommandLineParser parser = new PosixParser();
		try {
			CommandLine cmd = parser.parse(options, args);

			String[] unparsedArgs = cmd.getArgs();

			String fileToOpen = null;
			if (unparsedArgs.length == 1) {
				fileToOpen = unparsedArgs[0];
			}

			if (cmd.hasOption("?")) {
				HelpFormatter formatter = new HelpFormatter();
				formatter.printHelp("CombatLogConsole", options);
			}

			if (cmd.hasOption("c") && fileToOpen != null) {
				DisplayCommandLine(fileToOpen);
				return;
			} else {
				DisplayGUI(fileToOpen);
				return;
			}

		} catch (ParseException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public static String toCommandLineRepresentation(IBattleStatistic b) {
		DecimalFormat df = Configuration.getDecimalFormat();

		DateFormat sdf = Configuration.getDateTimeFormat();

		StringBuilder builder = new StringBuilder();

		Calendar start = Calendar.getInstance();
		start.setTimeInMillis(b.getBeginningMillis());
		Calendar stop = Calendar.getInstance();
		stop.setTimeInMillis(b.getEndingMillis());

		builder.append("Battle from: ");
		builder.append(sdf.format(start.getTime()));
		builder.append(" to: ");
		builder.append(sdf.format(stop.getTime()));
		builder.append("\n");

		builder.append("\tAll Damage Net dealt: ");
		builder.append(df.format(b.getNetDamageDealt().getAllDamage()));
		builder.append("\n");

		builder.append("\tAll Damage Net received: ");
		builder.append(df.format(b.getNetDamageReceived().getAllDamage()));
		builder.append("\n");

		builder.append("\tAll Damage Raw dealt: ");
		builder.append(df.format(b.getRawDamageDealt().getAllDamage()));
		builder.append("\n");

		builder.append("\tAll Damage Raw received: ");
		builder.append(df.format(b.getRawDamageReceived().getAllDamage()));
		builder.append("\n");

		builder.append("\tSeconds played:");
		builder.append(b.getSecondsPlayed());
		builder.append("\n");

		builder.append("\tNet DPS dealt: ");
		builder.append(df.format(b.getNetDamageDealt().getDamagePerSecond()));
		builder.append("\n");

		builder.append("\tNet DPS received: ");
		builder.append(df.format(b.getNetDamageReceived().getDamagePerSecond()));

		builder.append("\tRaw DPS dealt: ");
		builder.append(df.format(b.getRawDamageDealt().getDamagePerSecond()));
		builder.append("\n");

		builder.append("\tRaw DPS received: ");
		builder.append(df.format(b.getRawDamageReceived().getDamagePerSecond()));

		return builder.toString();
	}

}
